package inutan.game.business;

import inutan.common.context.FlowContext;
import inutan.common.message.ActionErrorEnum;
import inutan.data.Item.ItemVal;
import inutan.data.Item.Subtype;
import inutan.data.Resource.Type;
import inutan.data.Reward.RewardVal;
import inutan.data.Tables;
import inutan.game.entity.prop.BaseItemInfo;
import inutan.game.prop.OperatePropInterface;
import inutan.game.context.GameUserContext;
import inutan.game.storage.StorageContext;
import org.ricks.common.utils.RandomUtils;
import org.ricks.net.AioSession;

import java.util.*;
import java.util.stream.Collectors;

public class GameFlowContext<T> extends FlowContext<T> {

    private GameUserContext gameUserContext;

    public GameFlowContext(AioSession session, T t) {
        super(session, t);
    }

    public GameUserContext getGameUserContext() {
        return gameUserContext;
    }

    public void setGameUserContext(GameUserContext gameUserContext) {
        this.gameUserContext = gameUserContext;
    }


//    /**
//     * 获得道具
//     * @param props
//     */
//    public void addProps(List<BaseItemInfo> props) {
//        Map<Integer, List<BaseItemInfo>> groupByType =  openProp(props).stream().collect(Collectors.groupingBy(x -> x.getItemType()));
//        groupByType.forEach((type, propList) -> ItemTypeManager.getOperatePropTask(type).addProp(this, propList));
//    }
//
//    /**
//     * 消耗道具
//     * @param props
//     */
//    public void useProps(List<BaseItemInfo> props) {
//        Map<Integer, List<BaseItemInfo>> groupByType =  openProp(props).stream().collect(Collectors.groupingBy(x -> x.getItemType()));
//        Map<OperatePropInterface , List<BaseItemInfo>> map = new HashMap<>();
//        groupByType.forEach((type, propList) -> {
//            OperatePropInterface operatePropInterface  = ItemTypeManager.getOperatePropTask(type);
//            ActionErrorEnum.itemNumErr.assertTrue(operatePropInterface.checkItemNum(this, propList));
//            map.put(operatePropInterface, propList);
//        });
//        System.err.println("道具消耗成功！！！" + props.getFirst().getItemType() + " " + props.getFirst().getCount());
//        map.forEach(((operatePropInterface, items) -> operatePropInterface.useProp(this, items)));
//    }
//
//
//    /**
//     * 打开道具
//     */
//    public List<BaseItemInfo> openProp(List<BaseItemInfo> itemInfos) {
//        //return ListUtil.empty();
//        List<BaseItemInfo> itemInfoList = itemInfos.stream().map(x -> {
//            switch (x.getItemType()) {
//                case Type.ITEM:
//                    ItemVal data = StorageContext.tables().getTbItem().get(x.getItemId());
//                    if (data.type == inutan.data.Item.Type.Package && data.subType == Subtype.PackageAutoOpen) {
//                        return addPropByReward(data.effectValue);
//                    } else return List.of(x);
//                default:
//                    return List.of(x);
//            }
//        }).flatMap(List::stream).collect(Collectors.toList());
//        return itemInfoList;
//    }
//
    /**
     * @Explain --> 根据RewardId 获得List<Item>
     * @Author yanwang
     * @Date 2023/4/10 18:59
     **/
    public List<BaseItemInfo> addPropByReward(int rewardId) {
        RewardVal data = StorageContext.tables().getTbReward().get(rewardId);
        List<BaseItemInfo> itemInfos = new ArrayList<>();
        if (data != null) {
            data.rewardInfoColumn.forEach(item -> {
                int count = item.maxNum == item.minNum ? item.maxNum : RandomUtils.randomInt(item.minNum, item.maxNum);
                BaseItemInfo vo = new BaseItemInfo();
                vo.setItemType(item.resourceType);
                vo.setItemId(item.resourceId);
                vo.setCount(count);
                itemInfos.add(vo);
            });
        }
        return itemInfos;
    }


    // 添加道具（支持自动展开）
    public void addProps(List<BaseItemInfo> props) {
        List<BaseItemInfo> finalItems = PropUnwrapManager.unwrap(this, props);
        finalItems.stream()
                .collect(Collectors.groupingBy(BaseItemInfo::getItemType))
                .forEach((type, items) ->
                        ItemTypeManager.getOperation(type).addProp(this, items));
    }

    // 消耗道具（带事务保证）
    public void useProps(List<BaseItemInfo> props) {
        List<BaseItemInfo> finalItems = PropUnwrapManager.unwrap(this, props);

        // 阶段1：校验所有道具
        Map<OperatePropInterface, List<BaseItemInfo>> operations = finalItems.stream()
                .collect(Collectors.groupingBy(item ->
                        ItemTypeManager.getOperation(item.getItemType())));

        operations.forEach((op, items) ->
                ActionErrorEnum.itemNumErr.assertTrue(op.checkItemNum(this, items)));

        // 阶段2：执行消耗（建议在此处添加事务边界）
        operations.forEach((op, items) -> op.useProp(this, items));
    }
}
